<?php
///////////////////////////////////////////////////////////////////////////////////////////////////////
//  这个文件是 JCAT PHP框架的一部，该项目和此文件 均遵循 GNU 自由软件协议
// 
//  Copyleft 2008 JeCat.cn(http://team.JeCat.cn)
//
//
//  JCAT PHP框架 的正式全名是：Jellicle Cat PHP Framework。
//  “Jellicle Cat”出自 Andrew Lloyd Webber的音乐剧《猫》（《Prologue:Jellicle Songs for Jellicle Cats》）。
//  JCAT 是一个开源项目，它像音乐剧中的猫一样自由，你可以毫无顾忌地使用JCAT PHP框架。
//  JCAT 由中国团队开发维护，是一个国际性的项目。
//  正在使用的这个版本是：0.3.1 / SVN信息：$Id: class.JCAT_GtkFSDialog.php 1119 2008-10-25 03:55:26Z alee $
//
//
//
//  相关的链接：
//    [主页] http://jcat.JeCat.cn
//    [HTTP下载] http://jcat.JeCat.cn/download
//    [在线文档] http://jcat.JeCat.cn/document
//    [社区] http://jj.jecat.cn/forum-7-1.html
//  不很相关：
//    [MP3] http://www.google.cn/search?q=jellicle+songs+for+jellicle+cats+Andrew+Lloyd+Webber
//    [VCD/DVD] http://www.google.cn/search?q=CAT+Andrew+Lloyd+Webber+video
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*-- Project Introduce --*/




/**
 * What's this Class ?
 *
 * @author		alee
 * @access		public
 */
class JCAT_GtkFSDialog extends JCAT_GtkDialog
{
	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	void
	 */
	public function JCAT_GtkFSDialog( $nAction=Gtk::FILE_CHOOSER_ACTION_OPEN, $sTitle=null ) 
	{
		if( $sTitle===null )
		{
			$sTitle = JCAT_Language::SentenceEx('JCAT GtkDesktop 文件系统选择窗口','JCAT',null) ;
		}
		
		JCAT_ASSERT::ASSERT_INT($nAction) ;
		JCAT_ASSERT::ASSERT_STRING($sTitle) ;
		

		// 创建主窗口
		$wndDlg = new GtkFileChooserDialog($nAction) ;
		$wndDlg->set_modal(true) ;
		$wndDlg->set_action($nAction) ;
		$wndBtnOk = $wndDlg->add_button('确定',Gtk::RESPONSE_OK) ;
		$wndDlg->add_button('取消',Gtk::RESPONSE_CANCEL) ;		
		$wndDlg->set_title($sTitle) ;
		
	
		// 使用全局默认路径
		$sDefaultDirectory = self::GetGlabalDefaultDirectory() ;
		if($sDefaultDirectory!==null)
		{
			$wndDlg->set_current_folder($sDefaultDirectory) ;
		}
		
		// 取消独立窗口
		$wndDlg->set_skip_pager_hint(true) ;
		$wndDlg->set_skip_taskbar_hint(true) ;
		
		// 事件
		$wndDlg->connect( 'response', array($this,'OnResponse') ) ;
		$wndBtnOk->connect( 'clicked', array($this,'OnOK') ) ;
		
		$this->SetWidget($wndDlg) ;
	}
	
	/**
	 *	
	 *
	 * @access	public
	 * @param	$nAction		int		
	 * @param	$sDefaultPath	string	缺省路径，可以是一个 目录 或 文件
	 * @param	$sFilterString	string	过滤器字符串
	 * @param	$bMultiple		bool	是否多选； 多选 以 数组格式(array) 返回， 单选 以字符串格式(string) 返回
	 * @param	$sTitle			string	对话框标题
	 * @return	string, array:string, null
	 * @static
	 */
	static public function Choose( $nAction=Gtk::FILE_CHOOSER_ACTION_OPEN, $sDefaultPath=null, $sFilterString=null, $bMultiple=false, $sTitle=null )
	{
		if( $sTitle===null )
		{
			$sTitle = JCAT_Language::SentenceEx('JCAT GtkDesktop 文件系统选择窗口','JCAT',null) ;
		}

		// 创建对话框
		$aDlg = new JCAT_GtkFSDialog($nAction,$sTitle) ;
		$wndDlg = $aDlg->GetWidget() ;
		
		// 预设路径		
		if( $sDefaultPath )
		{			
			// 预设 文件
			if( is_file($sDefaultPath) )
			{
				$wndDlg->set_filename($sDefaultPath) ;
			}
			
			// 预设 目录
			else
			{
				$wndDlg->set_current_folder($sDefaultPath) ;
			}
		}
		
		// 过滤器 字串
		if( $sFilterString!==null )
		{
			self::UseFilterString($wndDlg,$sFilterString) ;
		}

		// 多选 保存文件 或 创建目录  只能单选
		if( in_array($nAction,array(Gtk::FILE_CHOOSER_ACTION_SAVE,Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER)) )
		{
			$bUseMultiple = false ;
		}
		else
		{
			$bUseMultiple =& $bMultiple ;
		}
			
		// 多选
		$wndDlg->set_select_multiple($bUseMultiple) ;
		
		if( $aDlg->DoDialog() == Gtk::RESPONSE_CANCEL )
		{
			return null ;
		}

		// 返回多项(array)
		if($bMultiple)
		{
			$arrRet = $aDlg->GetAllSelectedPath() ;
			return ( !$arrRet or !count($arrRet) )? null: $arrRet ;
		}
		
		// 返回单项(string)
		else
		{
			$sPath = $aDlg->GetSelectedPath() ;
			return ($sPath)? $sPath: null ;		
		}
	}
	
	
	/**
	 * 设置缺省的文件或目录名称
	 * 
	 * @access	public
	 * @param	$sDefaultName	string		缺省的文件或目录名称
	 * @return	void
	 */
	public function SetDefaultName($sDefaultName)
	{
		$wndDialog = $this->GetWidget() ;
		$wndDialog->set_current_name($sDefaultName);
	}
	
	/**
	 * Enter description here...
	 *
	 * @access 	public
	 * @param 	GtkFileChooserDialog 	$wndDlg
	 * @param 	string 					$sFilterString
	 * @return 	void
	 * @static
	 */
	static public function UseFilterString( GtkFileChooserDialog $wndDlg, $sFilterString ) 
	{
		JCAT_ASSERT::ASSERT_STRING($sFilterString) ;
		$sString = trim($sFilterString) ;
		$sString = str_replace("\r",'',$sString) ;
		
		if( empty($sString) )
		{
			return ;
		}
		
		$arrLines = explode("\n",$sString) ;
		foreach($arrLines as $sLine)
		{
			list($sName,$sFilters) = explode("\t",$sLine) ;
			$arrFilters = explode('|',$sFilters) ;
			
			// 过滤器
			$aFilter = new GtkFileFilter();
			
			// 模版;pl09?
			foreach($arrFilters as $sPattern)
			{
				$aFilter->add_pattern($sPattern) ;
			}
			
			// 过滤器名称
			$aFilter->set_name($sName) ;
			
			$wndDlg->add_filter($aFilter) ;
		}
		
		
	}
	
	
	
	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	bool
	 */
	public function OnOK( GtkButton $wndButton=null ) 
	{
		// 正常响应 OnResponse 
		if( $wndButton===null )
		{
			$this->bEmitOnOKbyResponse = true ;
		}
		
		// 不是响应 OnResponse，直接响应 Ok Button ，
		// 在 选择目录， 且没有选中 任何目录情况下，点击 Ok Button， Gtk 不会触发 对话框的 OnResponse
		// 但是 JCAT 中 仍然希望能够 使用当前打开的目录。
		if( $wndButton and @$this->bEmitOnOKbyResponse )
		{
			$this->bEmitOnOKbyResponse = false ;
			return false ;
		}
		
		$wndMainWidget = $this->GetWidget() ;
		JCAT_ASSERT::ASSERT_INSTANCE($wndMainWidget,'GtkDialog',JCAT_Language::SentenceEx('尚未初始化主窗体。','JCAT',null)) ;
		
		$aAction = $wndMainWidget->get_action() ;
		
		switch($aAction)
		{
			// 打开文件
			case Gtk::FILE_CHOOSER_ACTION_OPEN :
				
				$arrFileDirs = $wndMainWidget->get_filenames() ;

				// 选中 一个 即可
				if( count($arrFileDirs) )
				{
					$this->sSelectedPath = $wndMainWidget->get_filename() ;
					$this->arrAllSelectedPath = $arrFileDirs ;
				}
				
				// 未选中任何内容
				else
				{
					print "no file be selected\r\n" ;
					return false ;
				}
		
				break ;
			
			// 保存文件
			case Gtk::FILE_CHOOSER_ACTION_SAVE :
				
				// 未选中任何内容
				if( !$sFile = $wndMainWidget->get_filename() )
				{
					return false ;
				}
				
				// 提示覆盖
				if( is_file($sFile) and $this->GetOverwriteConfirmation() )
				{					
					$nRes = JCAT_Gtk::MessageDialog(
							JCAT_Language::SentenceEx("文件已经存在，是否覆盖此文件？\r\n%s",'JCAT',null,$sFile) ,
							JCAT_Language::SentenceEx('如何处理已经存在的文件？','JCAT',null),
							Gtk::MESSAGE_QUESTION,
							Gtk::BUTTONS_YES_NO 
					) ;
					
					if( Gtk::RESPONSE_NO == $nRes )
					{
						return false ;
					}
				}
				
				$this->sSelectedPath = $wndMainWidget->get_filename() ;
				$this->arrAllSelectedPath = $wndMainWidget->get_filenames() ;
				
				break ;

			// 打开文件夹
			case Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER :
				
				// 所有选中 的 内容
				$arrSelectedDirs = array() ;
				$arrFileOrDirs = $wndMainWidget->get_filenames() ;
				foreach ($arrFileOrDirs as $sFileOrDirPath)
				{
					if( is_dir($sFileOrDirPath) )
					{
						$arrSelectedDirs[] = $sFileOrDirPath ;
					}
				}
				
				// 没有选择任何目录，当使用前打开的目录
				if( !count($arrSelectedDirs) )
				{
					$this->sSelectedPath = $wndMainWidget->get_current_folder() ;
					$this->arrAllSelectedPath = array($this->sSelectedPath) ;
				}
				
				else 
				{
					// 多选
					$this->arrAllSelectedPath = $arrSelectedDirs ;
					
					// 选中
					$sSelectedPath = $wndMainWidget->get_filename() ;
					$this->sSelectedPath = is_dir($sSelectedPath)? $sSelectedPath: array_shift($arrSelectedDirs) ;
				}
				
				break ;
			
			default :
				break ;
		}
		
		
		// 设置全局默认路径
		self::SetGlabalDefaultDirectory($this->sSelectedPath) ;
		
		// 返回对话框
		return parent::OnOK() ;
	}
	
	/**
	 * 
	 *
	 * @access	public
	 * @param	$sPattern		string,array		What's this Parameter ?
	 * @param	$sName=null	string			What's this Parameter ?
	 * @param	$bDefault=false	bool			What's this Parameter ?
	 * @return	void
	 */
	public function AddFilter($Pattern,$sName=null,$bDefault=false)
	{
		JCAT_ASSERT::ASSERT_ISTHESE($Pattern,array('string','array:string')) ;
		JCAT_ASSERT::ASSERT_ISTHESE($sName,array('string','null')) ;
		
		if( is_string($Pattern) )
		{
			$arrPattern = array($Pattern) ;
		}
		else if( is_array($Pattern) )
		{
			$arrPattern =& $Pattern ;
		}
		else
		{
			JCAT_ASSERT::ASSERT_(0,'!?') ;
		}
		
		// 对话框窗体
		$wndMainWidget = $this->GetWidget() ;
		JCAT_ASSERT::ASSERT_INSTANCE($wndMainWidget,'GtkDialog',JCAT_Language::SentenceEx('尚未初始化主窗体。','JCAT',null)) ;

		
		// 过滤器
		$aFilter = new GtkFileFilter();
		foreach($arrPattern as $sPattern)
		{
			$aFilter->add_pattern($sPattern) ;
		}
		
		// 名称
		if( $sName===null )
		{
			$sName = implode(' | ',$arrPattern) ;
		}
		$aFilter->set_name($sName) ;
			
		$wndMainWidget->add_filter($aFilter) ;
		
		// 默认
		if( $bDefault )
		{
			$wndMainWidget->set_filter($aFilter) ;
		}
	}
	
	
	
	
	/**
	 * 
	 *
	 * @access	public
	 * @return	string, null
	 */
	public function GetSelectedPath()
	{
		return $this->sSelectedPath ;
	}
	/**
	 * 
	 *
	 * @access	public
	 * @return	string, null
	 */
	public function GetAllSelectedPath()
	{
		return $this->arrAllSelectedPath ;
	}
	
	
	
	/**
	 * 
	 *
	 * @access	public
	 * @param	$bOverwriteConConfirmation		What's this Parameter ?
	 * @return	void
	 */
	public function SetOverwriteConfirmation($bOverwriteConConfirmation)
	{
		$this->bOverwriteConConfirmation = $bOverwriteConConfirmation? true: false ;
	}
	
	/**
	 * 
	 *
	 * @access	public
	 * @param	$		What's this Parameter ?
	 * @return	bool
	 */
	public function GetOverwriteConfirmation()
	{
		return $this->bOverwriteConConfirmation ;
	}
	

	/**
	 * 
	 *
	 * @access	public
	 * @return	string
	 */
	static public function GetGlabalDefaultDirectory ()
	{
		return self::$sGlabalDefaultDirectory;
	}
	
	/**
	 * 
	 *
	 * @access	public
	 * @param	$sGlabalDefaultDirectory	string, null		What's this Parameter ?
	 * @return	string
	 */
	static public function SetGlabalDefaultDirectory ($sPath)
	{
		if($sPath===null)
		{
			$sDirectory=null ;
		}
		
		else 
		{
			if( is_dir($sPath) )
			{
				$sDirectory = $sPath ;
			}
			else
			{
				$sDirectory = dirname($sPath) ;
			}
			
			JCAT_ASSERT::ASSERT_DIR($sDirectory,JCAT_Language::SentenceEx('参数 $sPath(“%s”) 必须为存在的路径','JCAT',null,$sPath));
			$sDirectory = JCAT_Global::TidyPath($sDirectory);
		}
		
		$old_value = self::$sGlabalDefaultDirectory ;
		self::$sGlabalDefaultDirectory = $sDirectory;
		return $old_value ;
	}
	
	
	private $sSelectedPath ;
	private $arrAllSelectedPath ;
	
	private $bOverwriteConConfirmation = true ;
	
	
	/**
	 * 缺省全局目录 
	 * 
	 * @access	private
	 * @var		string
	 * @static	
	 */
	static private $sGlabalDefaultDirectory = null ;
	
}
?>